#include "msg_loop.h"

MessageLoopUI::MessageLoopUI()
    : m_dwThreadId( 0 )
{
}

MessageLoopUI::~MessageLoopUI()
{
}

DWORD MessageLoopUI::Run()
{
    m_Locker.Lock();
    m_dwThreadId = GetCurrentThreadId();
    m_Locker.Unlock();

    DWORD dwRetCode = 0;
    MSG msg;
    while( ::GetMessage( &msg, NULL, 0, 0 ) )
    {
        if( msg.message == WM_UI_QUIT )
        {
            dwRetCode = msg.wParam;
            break;
        }

        if( msg.message == WM_UI_MESSAGE )
        {
            Task *task = (Task*)msg.lParam;
            if( task )
            {
                ITaskDelegate *delegate = task->GetTaskDelegate();
                ITaskHandler *handler = task->GetTaskHandler();
                if( delegate && handler )
                {
                    delegate->OnDeglegate( task->GetTask(), handler, task->GetEventHandler() );
                }
                delete task;
            }
            continue;
        }

        ::TranslateMessage( &msg );
        ::DispatchMessage( &msg );
    }

    return dwRetCode;
}

BOOL MessageLoopUI::Pause()
{
    return FALSE;
}

BOOL MessageLoopUI::Continue()
{
    return FALSE;
}

DWORD MessageLoopUI::Quit( DWORD dwTimeout, DWORD dwRetCode )
{
    AutoLocker_(m_Locker);
    if( m_dwThreadId )
    {
        ::PostThreadMessage( m_dwThreadId, WM_UI_QUIT, dwRetCode, 0 );
    }
    m_dwThreadId = 0;

    return dwRetCode;
}

BOOL MessageLoopUI::PostQueueTask( ITaskDelegate * pTaskDelegate, DWORD nTask, ITaskHandler * pTaskHandler )
{
    if( !pTaskDelegate || !pTaskHandler )
    {
        return FALSE;
    }

    AutoLocker_(m_Locker);
    if( m_dwThreadId )
    {
        Task * task = new Task( pTaskDelegate, nTask, pTaskHandler, m_hEvent );
        if( task )
        {
            ::PostThreadMessage( m_dwThreadId, WM_UI_MESSAGE, 0, (LPARAM)task );
        }

        return TRUE;
    }

    return FALSE;
}

BOOL MessageLoopUI::IsCurrentThread( DWORD dwThreadId )
{
    AutoLocker_(m_Locker);
    return m_dwThreadId == dwThreadId;
}

BOOL MessageLoopUI::IsRunning()
{
    AutoLocker_(m_Locker);
    return m_dwThreadId == 0;
}